package com.investmenttechnologyservices.model;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.Key;

public class Account extends EntityHolder {
	//@Id 
	//private String key; // account key - short identifier or accountId;
	//private String name;
	//private String accountUserId; // UserId to access bank/brokerage info
	//private String accountId;
	//private String accountPassword; // encrypted or stored in cookie on client?
	//private Key<Bank> bankKey;
	//@Parent??
	//private Key firmKey;
	//private CashManagementType cashManagementType;
	//private Key<Account> cashAccountKey; // Can be NULL. Points to cash account used as default
	//@NotSaved(IfDefault.class)
	//private Map<String, AccountAuthorizationType> accountAuthorizations = null; // use UserId (getUserId())
	//@NotSaved(IfDefault.class)
	//private List<String> defaultTags = null; //tags automatically assigned to any position in this account 
	//private Date lastLoadedDate

	public Account(Entity entity) {
		super(entity);
	}
	
	public Account(String name, String accountUserId, String accountId, 
			String accountPassword, Key firmKey, Key bankKey, CashManagementType cashManagementType,
			Key cashAccountKey, Map<String, AccountAuthorizationType> accountAuthorizations,
			Set<String> defaultTags, Date lastLoadedDate) {
		super("account", firmKey);
		
		setName(name);
	
		setAccountId(accountId);
		setAccountPassword(accountPassword);
		setBankKey(bankKey);
		setCashManagementType(cashManagementType);
		setCashAccountKey(cashAccountKey);
	//	setAccountAuthorizations(accountAuthorizations);
		setDefaultTags(defaultTags);
		setLastLoadedDate(lastLoadedDate);
	}

	public Account(String name, String accountUserId, String accountId, String accountPassword, 
			Key firmKey, Key bankKey, CashManagementType cashManagementType, Set<String> defaultTags) {
		this(name, accountUserId, accountId, accountPassword, firmKey, bankKey, 
				cashManagementType, null, null, defaultTags, null);
	}

	public Account(Key firmKey, String name, Set<String> defaultTags) {
		this(name, null, null, null, firmKey, null, null, null, null, defaultTags, null);
	}

	public String getId() {
		return super.getId();
	}
	
	public Key getKey() {
		return super.getKey();
	}
	
	public Key getFirmKey() {
		return super.getParentKey();
	}

	public String getName() {
		return (String) getProperty("name");
	}

	public void setName(String name) {
		setProperty("name", name);
	}

	public void setAccountUserId(String accountUserId) {
		setUnindexedProperty("accountUserId",accountUserId, true);	
	}
	public String getAccountUserId() {return (String) getProperty("accountUserId");}

	public void setAccountId(String accountId) {
		setProperty("accountId",accountId,true);	
	}
	public String getAccountId() {return (String)getProperty("accountId");}
	
	public void setAccountPassword(String accountPassword) {
		setUnindexedProperty("accountPassword",accountPassword, true);	
	}
	public String getAccountPassword() {return (String)getProperty("accountPassword");}
	
	public void setBankKey(Key bankKey) {
		setProperty("bankKey",bankKey,true);	
	}
	public Key getBankKey() {return (Key)getProperty("bankKey");}
	/**
	 * This method sets the entity entry 'cashManagementType' if the enum is other than 
	 * BOTH_CASH_AND_INSTRUMENT (the default value).
	 * 
	 * @param cashManagementType
	 */
	public void setCashManagementType(CashManagementType cashManagementType) {
		if (cashManagementType == null || cashManagementType == CashManagementType.BOTH_CASH_AND_INSTRUMENT) {
			setProperty("cashManagementType",null, true);
		} else {
			setProperty("cashManagementType",cashManagementType);
		}
	}
	/**
	 * This method gets entity entry 'cashManagementType' if no value was stored then the enum is set to 
	 * BOTH_CASH_AND_INSTRUMENT (the default value).
	 * @return
	 */
	public CashManagementType getCashManagementType() {
		CashManagementType cashManagementType;
		String strCashManagementType = (String) getProperty("cashManagementType");
		if (strCashManagementType == null)
			 cashManagementType = CashManagementType.BOTH_CASH_AND_INSTRUMENT;
		else
			cashManagementType = CashManagementType.valueOf(strCashManagementType);
		return cashManagementType;
	}
	
	public void setCashAccountKey(Key cashAccountKey) {
		setProperty("cashAccountKey",cashAccountKey);	
	}
	public Key getCashAccountKey() {
		return (Key)getProperty("cashAccountKey");
	}

	public void setAccountAuthorizations(Map<String,AccountAuthorizationType> accountAuthorizations) {
		Map<String, String> accountAuthorizationsString = new HashMap<String, String>();
		for (Map.Entry<String, AccountAuthorizationType> entry : accountAuthorizations.entrySet() ) {
			accountAuthorizationsString.put(entry.getKey(), entry.getValue().name());
		}
		setProperty("accountAuthorizations",accountAuthorizationsString,true); 
	}
	public Map<String, AccountAuthorizationType> getAccountAuthorizations() {
		@SuppressWarnings("unchecked")
		Map<String, String> accountAuthorizationsString = (Map<String, String>) getProperty("accountAuthorizations");
		Map<String, AccountAuthorizationType> accountAuthorizations = new HashMap<String, AccountAuthorizationType>();
		for (Map.Entry<String, String> entry : accountAuthorizationsString.entrySet()) {
			accountAuthorizations.put(entry.getKey(), AccountAuthorizationType.valueOf(entry.getValue()));
		}
		return accountAuthorizations;
	}

	public void setDefaultTags(Set<String> defaultTags) {
		setProperty("defaultTags",defaultTags == null ? null : new ArrayList<String>(defaultTags));
	}
	@SuppressWarnings("unchecked")
	public List<String> getDefaultTags() {
		return (List<String>)getProperty("defaultTags");
	}
	
	public void setLastLoadedDate(Date lastLoadedDate) {
		if (lastLoadedDate == null) {
			lastLoadedDate = new Date();
		}
		setProperty("lastLoadedDate",lastLoadedDate);
	}
	public Date getLastLoadedDate() {return (Date)getProperty("lastLoadedDate");}
	
}
